import Controlled from "./components/Controlled"
import UnControlled from "./components/UnControlled"

function ControlledOrUncontrolled() {
  return (
    <div>
      <h1>解释 React 的“受控组件”与“非受控组件”区别及适用场景</h1>
      <p>在 React 中，受控组件与非受控组件是两种常见的表单元素处理方式。他们的主要区别在于数据的管理和更新方式，理解这两者的区别对于更好地构建 React 应用至关重要。</p>
      <p>下面我将详细讲解它们地概念、区别和适用场景。</p>
      
      <h3>1. 受控组件</h3>
      <h4>定义：</h4>
      <p>受控组件是指其表单元素的值由 React 组件的状态（state）管理。也就是说，组件的每次输入都会触发一个事件（如 onChange），然后更新组件的状态，从而使得表单元素的值始终与 React 的状态保持同步。</p>

      <h4>工作原理：</h4>
      <p>在 React 中，每个表单元素的值都有 state 进行控制，并通过 props 传递表单元素。我们通常会通过 onChange 事件监听用户的输入变化，并在事件回调中更新状态。这个状态的变化会导致组件重新渲染，表单元素的值随之更新。</p>

      <Controlled />

      <h4>在上述例子中：</h4>
      <p>1. {'value={value}'}：</p>使得 input 的值由组件的状态 value 控制。
      <p>2. { 'onChange={handleChange}' }：</p>当用户在输入框中输入时，会调用 handleChange 函数，更新状态，从而触发组件重新渲染并更新 input 的值。

      <h4>优点：</h4>
      <p>1. 表单数据统一管理：所有输入数据都保存在 React 的状态中，便于进行集中管理和验证。</p>
      <p>2. 便于调试和测试：因为所有的表单值都在 React 中管理，数据流动清晰，容易进行调试和单元测试。</p>
      <p>3. 灵活性：可以方便地将表单值与其他组件、外部 API 或状态管理库（如 Redux）连接。</p>

      <h4>适用场景：</h4>
      <p>1. 需要进行表单验证、数据处理或提交时，受控组件是首选。</p>
      <p>2. 当需要实现即使反馈、联动组件（比如根据用户输入显示建议）等复杂交互时，受控组件能提供更高的灵活性。</p>

      <h3>2. 非受控组件</h3>
      <h4>定义：</h4>
      <p>非受控组件与受控组件相对，其表单元素的值由 DOM 自身管理，而不是由 React 的状态控制。在这种方式下，React 组件通过 ref 获取对 DOM 元素的引用，而不直接管理它的状态。</p>
      
      <h4>工作原理：</h4>
      <p>非受控组件的值由 DOM 控制， React 只负责通过 ref 读取这些值。在组件中，我们可以通过 { 'React.createRef()' } 创建一个引用，并适用该引用获取到表单元素的当前值。</p>
    
      <UnControlled />

      <h4>在上述代码中：</h4>
      <p>1. {'ref={inputRef}'}：</p>为 input 元素创建一个引用 inputRef，React 不控制输入框的值，而是通过 inputRef.current.value 直接访问。
      <p>2. handleSubmit 函数通过 inputRef.current.value 获取输入框当前值，并在点击按钮时展示。</p>

      <h4>有点：</h4>
      <p>1. 简单易用：对于不需要对表单元素进行大量操作或验证的简单场景，非受控组件的实现方式简单，减少了不必要的复杂性。</p>
      <p>2. 性能：对于非常大的表单，非受控组件可以减少不必要的渲染，因为不需要频繁地更新状态。</p>

      <h4>缺点：</h4>
      <p>1. 无法直接访问状态：由于表单元素地值由 DOM 控制，React 无法方便地访问和管理表单数据，这可能使得在复杂场景下难以进行数据验证、处理和联动。</p>
      <p>2. 不容易实现功能：如果要实现数据绑定、验证等功能，非受控组件不如受控组件方便。</p>

      <h4>适用场景：</h4>
      <p>1. 适用于简单的表单，例如仅仅是提交一个表单，且没有复杂的数据验证和联动操作时。</p>
      <p>2. 适用于当表单值变化频率不高，且不需要在 React 中追踪其状态时，非受控组件更加高效。</p>
    </div>
  )
}

export default ControlledOrUncontrolled